package com.func.domain.activity.service.quota;

import com.func.domain.activity.model.aggregate.CreateQuotaOrderAggregate;
import com.func.domain.activity.model.entity.*;
import com.func.domain.activity.model.valobj.OrderTradeTypeVO;
import com.func.domain.activity.repository.IActivityRepository;
import com.func.domain.activity.service.IRaffleActivityAccountQuotaService;
import com.func.domain.activity.service.quota.policy.ITradePolicy;
import com.func.domain.activity.service.quota.rule.IActionChain;
import com.func.domain.activity.service.quota.rule.factory.DefaultActivityChainFactory;
import com.func.types.enums.ResponseCode;
import com.func.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Map;

/**
 * <p>
 * AbstractRaffleActivity
 * </p>
 *
 * @author Simon
 * @version 2025.03.11.1.0.0
 * @description AbstractRaffleActivity  抽奖活动抽象类, 定义标准的流程
 * @since 2025-03-11
 */

@Slf4j
public abstract class AbstractRaffleActivityAccountQuota extends RaffleActivitySupport implements IRaffleActivityAccountQuotaService {

    // 不同类型的交易策略实现类, 通过构造函数注入到Map中
    private final Map<String, ITradePolicy> tradePolicyGroup;
    public AbstractRaffleActivityAccountQuota(IActivityRepository activityRepository, DefaultActivityChainFactory defaultActivityChainFactory, Map<String, ITradePolicy> tradePolicyGroup) {
        super(activityRepository, defaultActivityChainFactory);
        this.tradePolicyGroup = tradePolicyGroup;
    }


    @Override
    public UnpaidActivityOrderEntity createOrder(SkuRechargeEntity skuRechargeEntity) {
        //1. 参数校验, 是不是传进来的SkuRecharge中的数据都是合法的
        String userId = skuRechargeEntity.getUserId();
        Long sku = skuRechargeEntity.getSku();
        String outBusinessNo = skuRechargeEntity.getOutBusinessNo();
        if(null == sku || StringUtils.isBlank(userId) || StringUtils.isBlank(outBusinessNo)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo() + skuRechargeEntity);
        }

        // 2. 查询未支付的订单 [一个月以内未支付的订单]
        UnpaidActivityOrderEntity unpaidActivityOrderEntity = activityRepository.queryUnpaidActivityOrder(skuRechargeEntity);
        if (null != unpaidActivityOrderEntity) return unpaidActivityOrderEntity;

        // 3. 查询基础信息
        // 3.1. 通过SKU查询活动信息
        ActivitySkuEntity activitySkuEntity =  queryActivitySku(skuRechargeEntity.getSku());
        // 3.2. 查询活动信息
        ActivityEntity activityEntity = queryActivityByActivityId(activitySkuEntity.getActivityId());
        // 3.3. 查询次数信息, 用户在活动上可参与的次数
        ActivityCountEntity activityCountEntity = queryActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());
        log.info("查询结果 : {} {} {}", activitySkuEntity, activityEntity, activityCountEntity);

        //4. 活动动作规则校验 [过滤失败则直接抛异常] 责任链扣减sku库存
        if (OrderTradeTypeVO.credit_pay_trade.equals(skuRechargeEntity.getOrderTradeTypeVO())){
            BigDecimal availableAmount = activityRepository.queryUserCreditAccountAmount(userId);
            if (availableAmount.compareTo(activitySkuEntity.getProductAmount()) < 0) {
                throw new AppException(ResponseCode.USER_CREDIT_ACCOUNT_NO_AVAILABLE_AMOUNT.getCode(), ResponseCode.USER_CREDIT_ACCOUNT_NO_AVAILABLE_AMOUNT.getInfo());
            }
        }
        IActionChain actionChain = defaultActivityChainFactory.openActionChain();
        boolean success = actionChain.action(activitySkuEntity, activityEntity, activityCountEntity);
        log.info("规则校验结果 : {}", success);

        // 5. 构建订单聚合对象
        CreateQuotaOrderAggregate createQuotaOrderAggregate = buildOrderAggregate(skuRechargeEntity, activitySkuEntity, activityEntity, activityCountEntity);

        // 6. 保存订单
        ITradePolicy tradePolicy = tradePolicyGroup.get(skuRechargeEntity.getOrderTradeTypeVO().getCode());
        tradePolicy.trade(createQuotaOrderAggregate);

        // 7. 返回订单信息
        ActivityOrderEntity activityOrderEntity = createQuotaOrderAggregate.getActivityOrderEntity();
        return UnpaidActivityOrderEntity.builder()
                .orderId(activityOrderEntity.getOrderId())
                .outBusinessNo(activityOrderEntity.getOutBusinessNo())
                .payAmount(activityOrderEntity.getPayAmount())
                .userId(userId)
                .build();

    }

    /**
     * 构建订单聚合对象
     * @param skuRechargeEntity 活动商品充值对象
     * @param activityEntity 活动实体
     * @param activityCountEntity 活动数量配置实体
     * @return 订单聚合对象
     */
    protected abstract CreateQuotaOrderAggregate buildOrderAggregate(SkuRechargeEntity skuRechargeEntity,ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity);

    public abstract Integer queryRaffleActivityAccountDayPartakeCount(Long activityId, String userId);

}

